iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Software Development

Haskell 從入門到放棄系列 第 10 篇

[Haskell 從入門到放棄] Day 10 - 再談 higher order function

  • 分享至 

  • xImage
  •  

Filter

filter 是傳入一個會回傳 Bool 的 function 及 List,然後將 List 中每個元素丟進去 function 最後回傳所有執行該 function 後為 True 的元素。

:t filter --filter :: (a -> Bool) -> [a] -> [a]

filter (>8) [1..10] -- [9,10]
filter (`elem` ['a'..'c']) ['a'..'e'] -- "abc"

其實使用起來跟 map 有八成像,都是傳入 function 及 List。

稍微敏銳的讀者應該會發現其實上面的行為我用 List comprehension 也是能夠做到一樣的事情的

其實 map 也是能用 List comprehension 做到一樣的事哦

[x| x <- [1..10] , x >8 ]
[x| x <- ['a'..'e'] , x `elem` ['a'..'c']]

那至於什麼時候要用 List comprehension 什麼時候要用 filter 或者 map ,我覺得就看個人喜好以及用哪種方式寫起來比較順手了,在多重限制條件下可能用 List comprehension 會比 filter 、map 較為易讀吧。

說回 filter 及 map ,他們應該也是 FP 中最常用到的function 了通常我們會同時用 map 與 filter 的各種組合技來將我們想要的資料給變出來。

像是

  1. 取得 List 中所有偶數的平方
  2. 取得 List 中所有正數的平方根
squareEven :: [Int] -> [Int]
squareEven xs = 
    map (^2) (filter even xs)

squareRootOfPositives :: [Double] -> [Double]
squareRootOfPositives xs =
    map sqrt (filter (> 0) xs)

squareEven 是先將偶數取出來後再經過 map 讓每個數都取平方

squareRootOfPositives 則是講將大於 0 的數值取出來後再開根號

大多數時候我們

Lamda

lamda 就是匿名函數,最常用在 higher order function 上,有時候要傳入的 function 邏輯可能非常複雜,但又不想為此額外宣告一個 function 那我們就會用 lamda 來幫助我們。

使用上只要加一個 \ 就好了。

filter (\ x -> x `mod` 3 == 0 ||  x `mod` 7 == 0) [1..30]
-- [3,6,7,9,12,14,15,18,21,24,27,28,30]

這邊 (\ x -> ...) 的 x 就是從 List 丟進去 lamda 的元素。

既然 lamda 像是一種 function 那我們當然可以繼續應用之前所說的特性像是 pattern matching,只是無法設置多個條件,所以其實是有機會發生 runtime error

map (\(x:xs) -> 2*x + sum xs) [[1..5],[5..10],[11,15]] -- [16,50,37]

我們可以藉此匹配到二維 List 中每個 List 的 第一個元素及剩下的元素並將第一個元素乘2後與剩下元素的加總相加。

也因為 curried function 的關係其實以下這兩種寫法是等價的

add:: Num a => a -> a -> a
add x y = x + y

add' :: Num a => a -> a -> a
add' = \x -> \y -> x + y

add' 剛好也很適合解釋 Num a => a -> a -> a 這個 type ,將第一次傳入的參數放進第一個 lamda 然後將第二次傳入的參數放進第二個 lamda


寫到現在相信讀者能夠開始體會到 FP 的好玩之處,會發現我們大多數時候是在想「資料要變什麼樣」而不是「要怎麼讓資料變成那樣」。


今天的程式碼

https://github.com/toddLiao469469/30days-for-haskell


上一篇
[Haskell 從入門到放棄] Day 09 - 終於來到 higher order function
下一篇
[Haskell 從入門到放棄] Day 11 - 繼續談 higher order function
系列文
Haskell 從入門到放棄 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言